class SrikiGenerator < Rails::Generator::NamedBase
  default_options :skip_migration => false
                  
  # TODO: remove unnecessary attributes
  attr_reader   :controller_name,
                :controller_class_path,
                :controller_file_path,
                :controller_class_nesting,
                :controller_class_nesting_depth,
                :controller_class_name,
                :controller_singular_name,
                :controller_plural_name,
                :controller_file_name
  alias_method  :controller_table_name, :controller_plural_name
  attr_reader   :model_controller_name,
                :model_controller_class_path,
                :model_controller_file_path,
                :model_controller_class_nesting,
                :model_controller_class_nesting_depth,
                :model_controller_class_name,
                :model_controller_singular_name,
                :model_controller_plural_name
  alias_method  :model_controller_file_name,  :model_controller_singular_name
  alias_method  :model_controller_table_name, :model_controller_plural_name
  
  

  def initialize(runtime_args, runtime_options = {})
    super
    
    @rspec = has_rspec?

    #@controller_name = args.shift || 'sessions'
    @model_controller_name = @name.pluralize

    # sessions controller
    #base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
    #@controller_class_name_without_nesting, @controller_file_name, @controller_plural_name = inflect_names(base_name)
    #@controller_singular_name = @controller_file_name.singularize

    #if @controller_class_nesting.empty?
    #  @controller_class_name = @controller_class_name_without_nesting
    #else
    #  @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
    #end

    # model controller
    base_name, @model_controller_class_path, @model_controller_file_path, @model_controller_class_nesting, @model_controller_class_nesting_depth = extract_modules(@model_controller_name)
    @model_controller_class_name_without_nesting, @model_controller_singular_name, @model_controller_plural_name = inflect_names(base_name)
    
    if @model_controller_class_nesting.empty?
      @model_controller_class_name = @model_controller_class_name_without_nesting
    else
      @model_controller_class_name = "#{@model_controller_class_nesting}::#{@model_controller_class_name_without_nesting}"
    end
  end                   

  def manifest
    recorded_session = record do |m|
      # Check for class naming collisions.
      m.class_collisions model_controller_class_path, "#{model_controller_class_name}PagesController", "#{model_controller_class_name}AssetsController", "#{model_controller_class_name}RevisionsController"
                                                      "#{model_controller_class_name}Helper"
      m.class_collisions class_path,                  "#{class_name}"

      # Controller, helper, views, and test directories.
      m.directory File.join('app/models', class_path)
      m.directory File.join('app/controllers', model_controller_class_path)

      m.directory File.join('app/controllers', model_controller_class_path)
      m.directory File.join('app/helpers', model_controller_class_path)
      m.directory File.join('app/views', model_controller_class_path, "#{file_name}_pages")
      m.directory File.join('app/views', model_controller_class_path, "#{file_name}_revisions")
      m.directory File.join('app/views', model_controller_class_path, "#{file_name}_assets")
      
      if @rspec
        m.directory File.join('spec/controllers', model_controller_class_path)
        m.directory File.join('spec/models', class_path)
        m.directory File.join('spec/fixtures', class_path)
      else
        m.directory File.join('test/functional', model_controller_class_path)
        m.directory File.join('test/unit', class_path)
      end

      # wiki models (page, revision, asset, image)
      m.template 'wiki_page.rb',
                  File.join('app/models',
                            class_path,
                            "#{file_name}_page.rb")
      m.template 'wiki_asset.rb',
                  File.join('app/models',
                            class_path,
                            "#{file_name}_asset.rb")
      m.template 'wiki_revision.rb',
                  File.join('app/models',
                            class_path,
                            "#{file_name}_revision.rb")
      m.template 'wiki_image.rb',
                  File.join('app/models',
                            class_path,
                            "#{file_name}_image.rb")                                                                                    

      # primary controllers 
      m.template 'wiki_pages_controller.rb',
                  File.join('app/controllers',
                            model_controller_class_path,
                            "#{model_controller_file_name}_pages_controller.rb")

      m.template 'wiki_assets_controller.rb',
                  File.join('app/controllers',
                            model_controller_class_path,
                            "#{model_controller_file_name}_assets_controller.rb")                            

      m.template 'wiki_revisions_controller.rb',
                  File.join('app/controllers',
                            model_controller_class_path,
                            "#{model_controller_file_name}_revisions_controller.rb")

      # view layer
      m.directory "app/views/#{file_name}_pages"
      m.directory "app/views/#{file_name}_revisions"
      m.directory "app/views/#{file_name}_assets"
            
      ## pages
      m.template 'wiki_pages/index.html.erb', "app/views/#{file_name}_pages/index.html.erb"  
      
      if @rspec
        m.template 'model_functional_spec.rb',
                    File.join('spec/controllers',
                              model_controller_class_path,
                              "#{model_controller_file_name}_controller_spec.rb")
        m.template 'unit_spec.rb',
                    File.join('spec/models',
                              class_path,
                              "#{file_name}_spec.rb")
        m.template 'fixtures.yml',
                    File.join('spec/fixtures',
                              "#{table_name}.yml")
      else
#        m.template 'functional_test.rb',
#                    File.join('test/functional',
#                              controller_class_path,
#                              "#{controller_file_name}_controller_test.rb")
#        m.template 'model_functional_test.rb',
#                    File.join('test/functional',
#                              model_controller_class_path,
#                              "#{model_controller_file_name}_controller_test.rb")
#        m.template 'unit_test.rb',
#                    File.join('test/unit',
#                              class_path,
#                              "#{file_name}_test.rb")
#        if options[:include_activation]
#          m.template 'mailer_test.rb', File.join('test/unit', class_path, "#{file_name}_mailer_test.rb")
#        end
#        m.template 'fixtures.yml',
#                    File.join('test/fixtures',
#                              "#{table_name}.yml")
      end

#      m.template 'model_helper.rb',
#                  File.join('app/helpers',
#                            model_controller_class_path,
#                            "#{model_controller_file_name}_helper.rb")


      # Controller templates
#      m.template 'login.html.erb',  File.join('app/views', controller_class_path, controller_file_name, "new.html.erb")
#      m.template 'signup.html.erb', File.join('app/views', model_controller_class_path, model_controller_file_name, "new.html.erb")

#      if options[:include_activation]
#        # Mailer templates
#        %w( activation signup_notification ).each do |action|
#          m.template "#{action}.html.erb",
#                     File.join('app/views', "#{file_name}_mailer", "#{action}.html.erb")
#        end
#      end

#      unless options[:skip_migration]
#        m.migration_template 'migration.rb', 'db/migrate', :assigns => {
#          :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
#        }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
#      end
#      
#      m.route_resource  controller_singular_name
#      m.route_resources model_controller_plural_name
    end

    action = nil
    action = $0.split("/")[1]
    case action
      when "generate" 
        puts
        puts ("-" * 70)
        puts "Don't forget to:"
        puts
        if options[:include_activation]
          puts "    map.activate '/activate/:activation_code', :controller => '#{model_controller_file_name}', :action => 'activate'"
          puts
          puts "  - add an observer to config/environment.rb"
          puts "    config.active_record.observers = :#{file_name}_observer"
          puts
        end
        if options[:stateful]
          puts "Also, don't forget to install the acts_as_state_machine plugin and set your resource:"
          puts
          puts "  svn co http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk vendor/plugins/acts_as_state_machine"
          puts
          puts %w(map.resources :#{model_controller_file_name}, :member => { :suspend => :put, :unsuspend => :put, :purge => :delete })
          puts
        end
        puts "Try these for some familiar login URLs if you like:"
        puts
        puts %(map.activate '/activate/:activation_code', :controller => '#{model_controller_file_name}', :action => 'activate', :activation_code => nil)
        puts %(map.signup '/signup', :controller => '#{model_controller_file_name}', :action => 'new')
        puts %(map.login '/login', :controller => '#{controller_file_name}', :action => 'new')
        puts %(map.logout '/logout', :controller => '#{controller_file_name}', :action => 'destroy')
        puts
        puts ("-" * 70)
        puts
      when "destroy" 
        puts
        puts ("-" * 70)
        puts
        puts "Thanks for using restful_authentication"
        puts
        puts "Don't forget to comment out the observer line in environment.rb"
        puts "  (This was optional so it may not even be there)"
        puts "  # config.active_record.observers = :#{file_name}_observer"
        puts
        puts ("-" * 70)
        puts
      else
        puts
    end

    recorded_session
  end

  def has_rspec?
    options[:rspec] || (File.exist?('spec') && File.directory?('spec'))
  end









end
